package pl.ciaastek.ubuntucontrol;

import java.io.IOException;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

import com.jcraft.jsch.Session;

public class Control extends Activity {

	public static Session session = null;
	final Connection conn = Profiles.conn;
	private final Context context = this;
	private String line, result, server, username, port, password;
	private int height;
	private SQLiteDatabase baza;
	private Cursor cursor;
	private LinearLayout layout;
	private LayoutInflater layoutInflater;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_control);
		final String username = getIntent().getStringExtra("username")
				.toString();
		final String server = getIntent().getStringExtra("server").toString();
		final String port = getIntent().getStringExtra("port").toString();
		final String password = getIntent().getStringExtra("password")
				.toString();
		setTitle(username + "@" + server);

		layout = (LinearLayout) findViewById(R.id.layout_main);
		layoutInflater = getLayoutInflater();
		View view;

		// Własne polecenie
		view = layoutInflater.inflate(R.layout.card, layout, false);
		final LinearLayout cc = (LinearLayout) view
				.findViewById(R.id.card_layout);

		cc.findViewById(R.id.card_menu).setVisibility(View.GONE);
		cc.findViewById(R.id.card_command).setVisibility(View.GONE);

		final LinearLayout ccTop = (LinearLayout) view
				.findViewById(R.id.card_top);
		final TextView ccTitle = (TextView) cc.findViewById(R.id.card_title);
		ccTitle.setText("Własne polecenie");
		final LinearLayout ccOut = (LinearLayout) cc
				.findViewById(R.id.card_desc);
		ccOut.getViewTreeObserver().addOnGlobalLayoutListener(
				new OnGlobalLayoutListener() {

					@Override
					public void onGlobalLayout() {
						height = ccOut.getHeight(); // Ahaha! Gotcha
						ccOut.getViewTreeObserver()
								.removeOnGlobalLayoutListener(this);
						ccOut.setVisibility(View.GONE);
					}

				});
		RelativeLayout ccTopRow = (RelativeLayout) cc
				.findViewById(R.id.card_top_row);
		final EditText command = new EditText(context);
		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
				RelativeLayout.LayoutParams.MATCH_PARENT,
				RelativeLayout.LayoutParams.WRAP_CONTENT);
		params.setMargins(20, 10, 20, 10);
		command.setLayoutParams(params);
		command.setSingleLine(true);
		command.setImeActionLabel("Wyślij", EditorInfo.IME_ACTION_SEND);
		command.setOnEditorActionListener(new OnEditorActionListener() {

			@Override
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if (actionId == EditorInfo.IME_ACTION_SEND) {
					InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(command.getWindowToken(), 0);
					if (command.getText().length() > 0) {
						new Exec(context, conn).execute(server, port, username,
								password, command.getText().toString());
						result = command.getText().toString() + ":\n";
						try {
							Thread.sleep(100);
						} catch (InterruptedException e1) {
							e1.printStackTrace();
						}
						try {
							while ((line = conn.fromServerExec.readLine()) != null) {
								result = result + "\n  " + line;
							}
						} catch (IOException e) {
							Log.v("Ubuntu Control", "coś się zjebało");
							e.printStackTrace();
						}
						TextView ccOutText = (TextView) ccOut
								.findViewById(R.id.card_desc_text);
						ccOutText.setText(result);
						height = ccOut.getMeasuredHeight();
						MyCustomAnimation a = new MyCustomAnimation(ccOut, 500,
								MyCustomAnimation.EXPAND);
						a.setHeight(height);
						ccOut.startAnimation(a);
					}
				}
				crossfadeOut(ccTitle, command, 500);

				return false;
			}
		});
		command.setVisibility(View.INVISIBLE);
		ccTopRow.addView(command);
		ImageButton card_desc_close = (ImageButton) ccOut
				.findViewById(R.id.card_desc_close);
		card_desc_close.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				MyCustomAnimation a = new MyCustomAnimation(ccOut, 500,
						MyCustomAnimation.COLLAPSE);
				height = a.getHeight();
				ccOut.startAnimation(a);

			}
		});

		layout.addView(cc);

		ccTop.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				crossfadeIn(ccTitle, command, 500);
			}
		});

		/*
		 * POBIERANIE MODUŁÓW Z BAZY
		 */
		baza = this.openOrCreateDatabase(conn.md5(username + "@" + server),
				MODE_PRIVATE, null);
		baza.execSQL("CREATE TABLE IF NOT EXISTS Modules (_id INTEGER PRIMARY KEY, name TEXT, command TEXT, output INT)");
		cursor = baza.rawQuery("SELECT * FROM Modules", null);
		if (cursor.moveToFirst()) {
			do {
				String dbName = cursor.getString(cursor.getColumnIndex("name"));
				String dbCommand = cursor.getString(cursor
						.getColumnIndex("command"));
				int dbOutput = cursor.getInt(cursor.getColumnIndex("output"));
				if (dbName.contentEquals("notify"))
					notifySend();
				else
					addModule(dbName, dbCommand, dbOutput, false);

			} while (cursor.moveToNext());
		}

		// add more
		view = layoutInflater.inflate(R.layout.card_add, layout, false);
		final LinearLayout add = (LinearLayout) view
				.findViewById(R.id.card_add_layout);
		add.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				AlertDialog.Builder add_module = new AlertDialog.Builder(
						context);
				add_module.setTitle("Dodaj moduł");
				CharSequence modules[] = { "Notify Send", "Kontrola muzyki",
						"Power Panel", "Własny moduł" };
				add_module.setItems(modules,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								switch (which) {
								case 0:
									int add_index = layout.indexOfChild(add);
									layout.removeViewAt(add_index);
									baza.execSQL("INSERT INTO Modules('name') Values('notify');");
									notifySend();
									layout.addView(add);
									break;
								case 3:
									addModule(null, null, 0, true);
								default:
									break;
								}

							}
						});
				add_module.show();
			}
		});
		layout.addView(add);
	}

	private void cardMenu(final View v) {
		ImageButton card_menu = (ImageButton) v.findViewById(R.id.card_menu);
		TextView card_title = (TextView) v.findViewById(R.id.card_title);
		final String title = card_title.getText().toString();
		PopupMenu popup = new PopupMenu(this, card_menu);
		MenuInflater inflater = popup.getMenuInflater();
		inflater.inflate(R.menu.card, popup.getMenu());
		popup.show();
		popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {

			public boolean onMenuItemClick(MenuItem item) {
				switch (item.getItemId()) {
				case R.id.card_menu_remove:
					AlertDialog.Builder sure = new AlertDialog.Builder(context);
					sure.setTitle("Usunąć kartę?");
					sure.setPositiveButton(android.R.string.yes,
							new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									baza.execSQL("DELETE FROM Modules WHERE name='"
											+ title + "'");
									layout.removeViewInLayout(v);
								}
							});
					sure.setNegativeButton(android.R.string.no, null);
					sure.show();
					break;
				case R.id.card_menu_edit:
					Toast.makeText(getApplicationContext(),
							"tutaj się będzie edytowało kartę",
							Toast.LENGTH_SHORT).show();
					break;

				default:
					break;
				}
				return false;
			}
		});
	}

	private void notifySend() {
		LinearLayout layout = (LinearLayout) findViewById(R.id.layout_main);
		LayoutInflater layoutInflater = getLayoutInflater();
		View view = layoutInflater.inflate(R.layout.card_notify_send, layout,
				false);
		final LinearLayout notify = (LinearLayout) view
				.findViewById(R.id.card_layout);
		final TextView card_title = (TextView) notify
				.findViewById(R.id.card_title);
		card_title.setText("Notify Send");
		TextView card_command = (TextView) notify
				.findViewById(R.id.card_command);
		card_command.setText("DISPLAY=:0 notify-send $1 $2");
		layout.addView(notify);
		final LinearLayout card_desc = (LinearLayout) notify
				.findViewById(R.id.card_desc);
		card_desc.getViewTreeObserver().addOnGlobalLayoutListener(
				new OnGlobalLayoutListener() {

					@Override
					public void onGlobalLayout() {
						// gets called after layout has been done but before
						// display
						// so we can get the height then hide the view

						height = card_desc.getHeight(); // Ahaha! Gotcha

						card_desc.getViewTreeObserver()
								.removeOnGlobalLayoutListener(this);
						card_desc.setVisibility(View.GONE);
					}

				});
		notify.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (card_desc.getVisibility() == View.VISIBLE) {
					MyCustomAnimation a = new MyCustomAnimation(card_desc, 500,
							MyCustomAnimation.COLLAPSE);
					height = a.getHeight();
					card_desc.startAnimation(a);
				} else {
					MyCustomAnimation a = new MyCustomAnimation(card_desc, 500,
							MyCustomAnimation.EXPAND);
					a.setHeight(height);
					card_desc.startAnimation(a);
				}
			}
		});
		final EditText notify_title = (EditText) notify
				.findViewById(R.id.card_notify_title);
		notify_title.setImeOptions(EditorInfo.IME_ACTION_NEXT);
		final EditText notify_body = (EditText) notify
				.findViewById(R.id.card_notify_body);
		notify_body.setImeActionLabel("Wyślij", EditorInfo.IME_ACTION_SEND);
		notify_body.setOnEditorActionListener(new OnEditorActionListener() {

			@Override
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if (actionId == EditorInfo.IME_ACTION_SEND) {
					if (notify_title.getText().length() > 0) {
						if (notify_body.getText().length() > 0) {
							send("DISPLAY=:0 notify-send \""
									+ notify_title.getText().toString()
									+ "\" \""
									+ notify_body.getText().toString() + "\"");
						} else {
							send("DISPLAY=:0 notify-send \""
									+ notify_title.getText().toString() + "\"");
						}
					} else {
						send("DISPLAY=:0 notify-send \" \" \""
								+ notify_body.getText().toString() + "\"");
					}
				}
				return false;
			}
		});
	}

	private void addModule(final String name, final String comm, final int out,
			boolean dialog) {
		final View view;
		if (dialog) {
			AlertDialog.Builder newmodule = new AlertDialog.Builder(context);
			newmodule.setTitle("Dodaj moduł");
			final LayoutInflater layout = LayoutInflater.from(this);
			final View nmd = layout.inflate(R.layout.new_module_dialog, null);

			newmodule.setView(nmd);

			newmodule.setPositiveButton("Dodaj",
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							EditText dialog_title = (EditText) nmd
									.findViewById(R.id.dialog_title);
							EditText dialog_command = (EditText) nmd
									.findViewById(R.id.dialog_command);
							CheckBox dialog_output = (CheckBox) nmd
									.findViewById(R.id.dialog_output);
							String mName = dialog_title.getText().toString();
							String mComm = dialog_command.getText().toString();
							int mOut;
							if (dialog_output.isChecked())
								mOut = 1;
							else
								mOut = 0;
							baza.execSQL("INSERT INTO Modules('name', 'command','output') Values('"
									+ mName
									+ "','"
									+ mComm
									+ "','"
									+ mOut
									+ "');");
							addModule(mName, mComm, mOut, false);
						}
					});
			newmodule.setNegativeButton(android.R.string.cancel, null);
			newmodule.show();
		} else {
			view = layoutInflater.inflate(R.layout.card, layout, false);
			LinearLayout card = (LinearLayout) view
					.findViewById(R.id.card_layout);
			TextView cardTitle = (TextView) card.findViewById(R.id.card_title);
			final TextView cardCommand = (TextView) card
					.findViewById(R.id.card_command);
			LinearLayout cardOutput = (LinearLayout) card
					.findViewById(R.id.card_desc);

			cardTitle.setText(name);
			cardCommand.setText(comm);
			if (out == 1)
				cardOutput.setVisibility(View.VISIBLE);
			else
				cardOutput.setVisibility(View.GONE);
			ImageButton card_menu = (ImageButton) view
					.findViewById(R.id.card_menu);
			card_menu.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					cardMenu(view);
				}
			});
			LinearLayout card_top = (LinearLayout) card
					.findViewById(R.id.card_top);
			card_top.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					send(cardCommand.getText().toString());

				}
			});
			layout.addView(card);
		}
	}

	public void send(String command) {
		new Exec(context, conn).execute(server, port, username, password,
				command);
	}

	private void closeAndDisconnect() {
		AlertDialog.Builder close = new AlertDialog.Builder(this);
		close.setTitle(R.string.close_dialog_title);
		close.setPositiveButton(android.R.string.yes,
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						if (conn.channel != null)
							conn.channel.disconnect();
						if (conn.session != null)
							conn.session.disconnect();
						finishAffinity();
					}
				});
		close.setNegativeButton(android.R.string.no, null);
		close.show();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		// case R.id.settings:
		// Intent intent = new Intent(context, SettingsActivity.class);
		// startActivity(intent);
		// break;
		case R.id.disconnect:
			closeAndDisconnect();
			break;
		}
		return true;
	}

	private void crossfadeOut(final TextView title, final EditText edit,
			int duration) {

		title.setAlpha(0f);
		title.setVisibility(View.VISIBLE);

		title.animate().alpha(1f).setDuration(duration).setListener(null);

		edit.animate().alpha(0f).setDuration(duration)
				.setListener(new AnimatorListenerAdapter() {
					@Override
					public void onAnimationEnd(Animator animation) {
						edit.setVisibility(View.INVISIBLE);
						edit.setText("");
					}
				});
	}

	private void crossfadeIn(final TextView title, final EditText edit,
			int duration) {

		edit.setAlpha(0f);
		edit.setVisibility(View.VISIBLE);

		edit.animate().alpha(1f).setDuration(duration).setListener(null);

		title.animate().alpha(0f).setDuration(duration)
				.setListener(new AnimatorListenerAdapter() {

					@Override
					public void onAnimationStart(Animator animation) {
						InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
						imm.showSoftInput(edit, InputMethodManager.SHOW_FORCED);
					}

					@Override
					public void onAnimationEnd(Animator animation) {
						title.setVisibility(View.GONE);
					}
				});
	}

	@Override
	public void onBackPressed() {
		closeAndDisconnect();
	}

}
